﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RENIT.DragNDropUpload.Utils;
using System.Web.UI.WebControls.WebParts;
using System.Threading;

namespace RENIT.DragNDropUpload.Extensibility
{
    public static class WebPartsAdaptersManager
    {
        private static List<IWebPartAdapter> adapters = new List<IWebPartAdapter>();
        private static object sync = new object();

        public static event Action OnAdaptersInitCallback;

        public static UploadTargetData GetTargetData(WebPart webPart)
        {
            var adaptersCache = GetAdaptersArray();
            var adapter = adaptersCache.FirstOrDefault(a => a.IsWebPartSupported(webPart));
            UploadTargetData result = null;
            if (adapter != null)
            {
                result = adapter.GetTargetData(webPart, adaptersCache);
            }
            return result;
        }

        private static IWebPartAdapter[] GetAdaptersArray()
        {
            IWebPartAdapter[] adaptersCache = null;
            lock (sync)
            {
                if (adapters.Count == 0)
                {
                    OnAdaptersInitCallback();
                }
                adaptersCache = adapters.ToArray();
            }
            return adaptersCache;
        }


        public static void InitAdapters(params IWebPartAdapter[] newAdapters)
        {
            lock (sync)
            {
                foreach (var adapter in newAdapters)
                {
                    if (!adapters.Contains(adapter))
                    {
                        adapters.Add(adapter);
                    }
                }
            }
        }


        public static void InitAdaptersDynamically(params string[] assemblyQualifiedAdapterClasses)
        {
            lock (sync)
            {
                foreach (var name in assemblyQualifiedAdapterClasses)
                {
                    bool typeLoaded = false;
                    foreach (var a in adapters)
                    {
                        var adapterTypeName = a.GetType().AssemblyQualifiedName;
                        if (adapterTypeName.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                        {
                            typeLoaded = true;
                            break;
                        }
                    }
                    if (typeLoaded)
                    {
                        continue;
                    }
                    try
                    {
                        var type = Type.GetType(name);
                        var adapter = Activator.CreateInstance(type) as IWebPartAdapter;
                        if (adapter == null)
                        {
                            continue;
                        }
                        adapters.Add(adapter);
                    }
                    catch (Exception err)
                    {
                        System.Diagnostics.Trace.WriteLine(err);
                    }
                }
            }
        }
    }
}
